/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author antonio
 */


/**
 *  Cuber si occupa di far partire le ricerca del modo selezionato
 *
 * this.executeRecursive() esegue la ricerca del modo _RECURSIVE_
 * this.executeDirect() esegue la ricerca del modo _DIRECT_
 * 
 */

import jargs.gnu.CmdLineParser;
import com.hp.hpl.jena.query.*;
import java.util.Vector;

import util.CubixResourceFactory;
import util.CubixQueryFactory;
import util.ExecuteSparqlQuery;

import cube.Cube;
import cube.CubeFactory;
import util.Person;

public class Cuber {

    private String graphUri;
    private String subUri;

    private Vector levelRoom;
    private Vector levelFloor;
    private Vector levelBlock;

    private CubixResourceFactory resourceFactory;

    //costruttore per il modo _RECURSIVE_
    public Cuber(String graphUri, String subUri)
    {
        this.graphUri = graphUri;
        this.subUri = subUri;

        this.levelRoom = new Vector();
        this.levelFloor = new Vector();
        this.levelBlock = new Vector();
    }

    //costruttore per il modo _DIRECT_
    public Cuber(String graphUri)
    {
        this.graphUri = graphUri;
    }


    /*
     * In TheCubix esitono tre livelli di posizione:
     *
     * - level 0 - livello di stanza
     * - level 1 - livello di piano
     * - level 2 - livello di edificio
     *
     * executeRecursive richiede in input dei parametri
     *
     * - level - il livello da cui si vuole partire per effettuare la ricerca
     * - resource - l'uri della risorsa del livello superiore rispetto a quello
     *              passato alla funzione nel parametro level
     *
     * Es: Se voglio cercare tutti gli utenti che si trovano nei vari piani del tribunale devo fare:
     *     executeRecursive(1, "http://unime.it/thecubix/TribunaleMessina")
     * 
     * */

    public void executeRecursive(int level, String resource)
    {
        if(level < 0)  //condizione uscita ricorsione
            return;    //sotto il livello zero (livello stanze) esci

        CubixResourceFactory rf = new CubixResourceFactory();
        rf.setOption(this.graphUri, resource);
        Vector lista = rf.createResource();

        for(int i=0; i<lista.size(); i++)
        {
            String sub = (String)lista.elementAt(i);
            CubixQueryFactory rq = new CubixQueryFactory(this.graphUri, sub);
            String query = rq.createQuery(level);

            ExecuteSparqlQuery x = new ExecuteSparqlQuery(query);
            ResultSet results = x.connect();

            this.executeRecursive(level-1, sub);

            switch(level)
            {
                case 2:

                    CubeFactory f2 = new CubeFactory(sub, this.graphUri);
                    Cube cubixBlock = f2.createCube();

                    System.out.println("block: " + sub);

                    Vector resourceIntoCubeBlock = new Vector();

                    while(results.hasNext())
                    {
                        QuerySolution soln = results.nextSolution();
                        String uri = soln.get("persone").toString();
                        System.out.println("person uri: " + uri);

                        String nome = soln.get("nome").toString();
                        System.out.println("person nome: " + nome);

                        String status = soln.get("status").toString();
                        System.out.println("person status: " + status);

                        Person p = new Person();
                        p.setUri(uri);
                        p.setNome(nome);
                        p.setStatus(status);

                        resourceIntoCubeBlock.add(p);
                    }

                    cubixBlock.setResourceIntoCube(resourceIntoCubeBlock);
                    cubixBlock.setSubLevelCube((Vector)this.levelFloor.clone());

                    this.levelBlock.add(cubixBlock);
                    this.levelFloor.clear();

                    break;

                case 1:

                    CubeFactory f1 = new CubeFactory(sub, this.graphUri);
                    Cube cubixFloor = f1.createCube();

                    System.out.println("floor: " + sub);

                    Vector resourceIntoCubeFloor = new Vector();

                    while(results.hasNext())
                    {
                        QuerySolution soln = results.nextSolution();
                        String uri = soln.get("persone").toString();
                        System.out.println("person uri: " + uri);

                        String nome = soln.get("nome").toString();
                        System.out.println("person nome: " + nome);

                        String status = soln.get("status").toString();
                        System.out.println("person status: " + status);

                        Person p = new Person();
                        p.setUri(uri);
                        p.setNome(nome);
                        p.setStatus(status);

                        resourceIntoCubeFloor.add(p);
                    }

                    cubixFloor.setResourceIntoCube(resourceIntoCubeFloor);
                    cubixFloor.setSubLevelCube((Vector)this.levelRoom.clone());

                    this.levelFloor.add(cubixFloor);
                    this.levelRoom.clear();

                    break;

                case 0:

                    CubeFactory f0 = new CubeFactory(sub, this.graphUri);
                    Cube cubixRoom = f0.createCube();

                    System.out.println("room: " + sub);

                    Vector resourceIntoCubeRoom = new Vector();

                    while(results.hasNext())
                    {
                        QuerySolution soln = results.nextSolution();
                        String uri = soln.get("persone").toString();
                        System.out.println("person uri: " + uri);

                        String nome = soln.get("nome").toString();
                        System.out.println("person nome: " + nome);

                        String status = soln.get("status").toString();
                        System.out.println("person status: " + status);

                        Person p = new Person();
                        p.setUri(uri);
                        p.setNome(nome);
                        p.setStatus(status);

                        resourceIntoCubeRoom.add(p);
                    }

                    cubixRoom.setResourceIntoCube(resourceIntoCubeRoom);
                    //cubixRoom.setSubLevelCube((Vector)this.levelRoom.clone());

                    this.levelRoom.add(cubixRoom);
                    //this.levelRoom.clear();

                    break;

            }
        }
    }

    public void executeDirect(String userUri)
    {

        String query = "select ?blocco ?piano ?aula from <" + this.graphUri + "> where" +
                "{<" + userUri +"> <http://unime.it/cubixprop#nelBlocco> ?blocco." +
                 "<" + userUri +"> <http://unime.it/cubixprop#nelPiano> ?piano." +
                 "<" + userUri +"> <http://unime.it/cubixprop#nelAula> ?aula}";

        ExecuteSparqlQuery x = new ExecuteSparqlQuery(query);
        ResultSet results = x.connect();

        QuerySolution soln = results.nextSolution();
        String blocco = soln.get("blocco").toString();
        String piano = soln.get("piano").toString();
        String aula = soln.get("aula").toString();

        System.out.println("Identifier User: ");
        System.out.println("uri :" + userUri);
        System.out.println("position level 2: " + blocco);
        System.out.println("position level 1: " + piano);
        System.out.println("position level 0: " + aula);
        

    }
}
